package com.vhall.component.plugin.core.service;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.plugin.common.constant.RedisKey;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.text.MessageFormat;
import java.util.Map;
import java.util.Objects;

/**
 * @author shimingming
 * @since 2023/8/18 9:58
 */
@Slf4j
public class BaseHttpService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public String httpGetAndPrintLog(String url, Map<String, Object> map) {

        long start = System.currentTimeMillis();
        String rsp;
        try {
            rsp = HttpUtil.get(url, map, 3000);
        } catch (Exception e) {
            log.error(MessageFormat.format("请求接口异常，请求路径：【{0}】，入参：【{1}】，异常原因：【{2}】 ", url, map.toString(), e));
            throw new BusinessException(e.getMessage());
        }
        long end = System.currentTimeMillis();
        String value = redisTemplate.opsForValue().get(RedisKey.PASS_LOG);
        if (StringUtils.isNotBlank(value)) {
            log.info(MessageFormat.format("请求接口，请求路径：【{0}】，入参：【{1}】，出参：【{2}】 ,耗时：【{3}】", url, map.toString(), rsp, end - start));
        }
        return rsp;
    }

    public String httpPostAndPrintLog(String url, Map<String, Object> map) {

        long start = System.currentTimeMillis();
        String rsp;
        try {
            rsp = HttpUtil.post(url, map, 3000);
        } catch (Exception e) {
            log.error(MessageFormat.format("请求接口异常，请求路径：【{0}】，入参：【{1}】，异常原因：【{2}】 ", url, map.toString(), e));
            throw new BusinessException(e.getMessage());
        }
        long end = System.currentTimeMillis();
        String value = redisTemplate.opsForValue().get(RedisKey.PASS_LOG);
        if (StringUtils.isNotBlank(value)) {
            log.info(MessageFormat.format("请求路径：【{0}】，入参：【{1}】，出参：【{2}】 ,耗时：【{3}】", url, map.toString(), rsp, end - start));
        }
        return rsp;
    }

    /**
     *
     * @param urlString
     * @param methodName
     * @return
     */
    public JSONObject httpRequestGetJsonObject(String urlString, String methodName) {
        return httpRequestGetJsonObject(urlString,methodName,true);
    }
    /**
     *
     * @param urlString
     * @param methodName
     * @param resultNotNull 结果是否可以为空
     * @return
     */
    public JSONObject httpRequestGetJsonObject(String urlString, String methodName,Boolean resultNotNull) {
        HttpRequest httpRequest = HttpRequest.get(urlString);
        log.info("调用三方服务{},请求体:{}", methodName, httpRequest.toString());
        HttpResponse execute = null;
        String body;
        try {
            execute = httpRequest.execute();
            body = execute.body();
        } catch (Exception e) {
            log.error("调用三方发生错误{},请求体:{},响应体:{}", methodName, httpRequest.toString(), execute, e);
            throw new BusinessException(BizErrorCode.BIZ_THIRD_FAILED);
        }

        JSONObject bodyJson = JSONObject.parseObject(body);
        if (!"0".equals(bodyJson.getString("code"))) {
            log.error("调用三方发生错误{},返回结果不符合预期,请求体:{},响应体:{}", methodName, httpRequest.toString(), execute);
            throw new BusinessException(BizErrorCode.BIZ_THIRD_FAILED);
        }
        JSONObject data = null;
        if (bodyJson.containsKey("data")) {
            String dataStr = bodyJson.getString("data");
            if(JSONUtil.isTypeJSONObject(dataStr)){
                data = JSONObject.parseObject(dataStr);
            }else{
                log.error("通过 三方 {} 发生错误,返回结果不符合预期,请求体:{},响应体:{}", methodName, httpRequest.toString(), execute);
            }
        }
        if (resultNotNull && Objects.isNull(data)) {
            log.error("通过 三方 {} 发生错误,返回结果不符合预期,请求体:{},响应体:{}", methodName, httpRequest.toString(), execute);
            throw new BusinessException(BizErrorCode.BIZ_THIRD_INFO_ERR);
        }
        log.info("{},返回结果为:{}", methodName, data);
        return data;
    }
    /**
     *
     * @param urlString
     * @param methodName
     * @param resultNotNull 结果是否可以为空
     * @return
     */
    public String httpRequestGetString(String urlString, String methodName,Boolean resultNotNull) {
        HttpRequest httpRequest = HttpRequest.get(urlString);
        log.info("调用三方服务{},请求体:{}", methodName, httpRequest.toString());
        HttpResponse execute = null;
        String body;
        try {
            execute = httpRequest.execute();
            body = execute.body();
        } catch (Exception e) {
            log.error("调用三方发生错误{},请求体:{},响应体:{}", methodName, httpRequest.toString(), execute, e);
            throw new BusinessException(BizErrorCode.BIZ_THIRD_FAILED);
        }

        JSONObject bodyJson = JSONObject.parseObject(body);
        if (!"0".equals(bodyJson.getString("code"))) {
            log.error("调用三方发生错误{},返回结果不符合预期,请求体:{},响应体:{}", methodName, httpRequest.toString(), execute);
            throw new BusinessException(BizErrorCode.BIZ_THIRD_FAILED);
        }
        String data = bodyJson.getString("data");
        if (resultNotNull && Objects.isNull(data)) {
            log.error("通过 三方 {} 发生错误,返回结果不符合预期,请求体:{},响应体:{}", methodName, httpRequest.toString(), execute);
            throw new BusinessException(BizErrorCode.BIZ_THIRD_INFO_ERR);
        }
        log.info("{},返回结果为:{}", methodName, data);
        return data;
    }
    /**
     *
     * @param urlString
     * @param methodName
     * @return
     */
    public JSONArray httpRequestGetJsonArray(String urlString, String methodName) {
        HttpRequest httpRequest = HttpRequest.get(urlString);
        log.info("调用三方服务{},请求体:{}", methodName, httpRequest.toString());
        HttpResponse execute = null;
        String body;
        try {
            execute = httpRequest.execute();
            body = execute.body();
        } catch (Exception e) {
            log.error("调用三方发生错误{},请求体:{},响应体:{}", methodName, httpRequest.toString(), execute, e);
            throw new BusinessException(BizErrorCode.BIZ_THIRD_FAILED);
        }

        JSONObject bodyJson = JSONObject.parseObject(body);
        if (!"0".equals(bodyJson.getString("code"))) {
            log.error("调用三方发生错误{},返回结果不符合预期,请求体:{},响应体:{}", methodName, httpRequest.toString(), execute);
            throw new BusinessException(BizErrorCode.BIZ_THIRD_FAILED);
        }
        JSONArray data = null;
        if (bodyJson.containsKey("data")) {
            String dataStr = bodyJson.getString("data");
            if(JSONUtil.isTypeJSONArray(dataStr)){
                data = bodyJson.getJSONArray("data");
            }
        }
        if (Objects.isNull(data)) {
            log.error("通过 三方 {} 发生错误,返回结果不符合预期,请求体:{},响应体:{}", methodName, httpRequest.toString(), execute);
            throw new BusinessException(BizErrorCode.BIZ_THIRD_INFO_ERR);
        }
        log.info("{},返回结果为:{}", methodName, data);
        return data;
    }

}
